{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pinecone-io/examples/blob/master/learn/generation/langchain/handbook/01-langchain-prompt-templates.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/pinecone-io/examples/blob/master/learn/generation/langchain/handbook/01-langchain-prompt-templates.ipynb)\n",
    "\n",
    "# Prompt Engineering\n",
    "\n",
    "In this notebook we'll explore the fundamentals of prompt engineering. We'll start by installing library prerequisites."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install langchain openai"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Structure of a Prompt\n",
    "\n",
    "A prompt can consist of multiple components:\n",
    "\n",
    "* Instructions\n",
    "* External information or context\n",
    "* User input or query\n",
    "* Output indicator\n",
    "\n",
    "Not all prompts require all of these components, but often a good prompt will use two or more of them. Let's define what they all are more precisely.\n",
    "\n",
    "**Instructions** tell the model what to do, typically how it should use inputs and/or external information to produce the output we want.\n",
    "\n",
    "**External information or context** are additional information that we either manually insert into the prompt, retrieve via a vector database (long-term memory), or pull in through other means (API calls, calculations, etc).\n",
    "\n",
    "**User input or query** is typically a query directly input by the user of the system.\n",
    "\n",
    "**Output indicator** is the *beginning* of the generated text. For a model generating Python code we may put `import ` (as most Python scripts begin with a library `import`), or a chatbot may begin with `Chatbot: ` (assuming we format the chatbot script as lines of interchanging text between `User` and `Chatbot`).\n",
    "\n",
    "Each of these components should usually be placed the order we've described them. We start with instructions, provide context (if needed), then add the user input, and finally end with the output indicator."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "prompt = \"\"\"Answer the question based on the context below. If the\n",
    "question cannot be answered using the information provided answer\n",
    "with \"I don't know\".\n",
    "\n",
    "Context: Large Language Models (LLMs) are the latest models used in NLP.\n",
    "Their superior performance over smaller models has made them incredibly\n",
    "useful for developers building NLP enabled applications. These models\n",
    "can be accessed via Hugging Face's `transformers` library, via OpenAI\n",
    "using the `openai` library, and via Cohere using the `cohere` library.\n",
    "\n",
    "Question: Which libraries and model providers offer LLMs?\n",
    "\n",
    "Answer: \"\"\""
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this example we have:\n",
    "\n",
    "```\n",
    "Instructions\n",
    "\n",
    "Context\n",
    "\n",
    "Question (user input)\n",
    "\n",
    "Output indicator (\"Answer: \")\n",
    "```\n",
    "\n",
    "Let's try sending this to a GPT-3 model. We will use the LangChain library but you can also use the `openai` library directly. In both cases, you will need [an OpenAI API key](https://beta.openai.com/account/api-keys).\n",
    "\n",
    "We initialize a `text-davinci-003` model like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.llms import OpenAI\n",
    "\n",
    "# initialize the models\n",
    "openai = OpenAI(\n",
    "    model_name=\"text-davinci-003\",\n",
    "    openai_api_key=\"YOUR_API_KEY\"\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And make a generation from our prompt."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " Hugging Face's `transformers` library, OpenAI using the `openai` library, and Cohere using the `cohere` library.\n"
     ]
    }
   ],
   "source": [
    "print(openai(prompt))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We wouldn't typically know what the users prompt is beforehand, so we actually want to add this in. So rather than writing the prompt directly, we create a `PromptTemplate` with a single input variable `query`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain import PromptTemplate\n",
    "\n",
    "template = \"\"\"Answer the question based on the context below. If the\n",
    "question cannot be answered using the information provided answer\n",
    "with \"I don't know\".\n",
    "\n",
    "Context: Large Language Models (LLMs) are the latest models used in NLP.\n",
    "Their superior performance over smaller models has made them incredibly\n",
    "useful for developers building NLP enabled applications. These models\n",
    "can be accessed via Hugging Face's `transformers` library, via OpenAI\n",
    "using the `openai` library, and via Cohere using the `cohere` library.\n",
    "\n",
    "Question: {query}\n",
    "\n",
    "Answer: \"\"\"\n",
    "\n",
    "prompt_template = PromptTemplate(\n",
    "    input_variables=[\"query\"],\n",
    "    template=template\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can insert the user's `query` to the prompt template via the `query` parameter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Answer the question based on the context below. If the\n",
      "question cannot be answered using the information provided answer\n",
      "with \"I don't know\".\n",
      "\n",
      "Context: Large Language Models (LLMs) are the latest models used in NLP.\n",
      "Their superior performance over smaller models has made them incredibly\n",
      "useful for developers building NLP enabled applications. These models\n",
      "can be accessed via Hugging Face's `transformers` library, via OpenAI\n",
      "using the `openai` library, and via Cohere using the `cohere` library.\n",
      "\n",
      "Question: Which libraries and model providers offer LLMs?\n",
      "\n",
      "Answer: \n"
     ]
    }
   ],
   "source": [
    "print(\n",
    "    prompt_template.format(\n",
    "        query=\"Which libraries and model providers offer LLMs?\"\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " Hugging Face's `transformers` library, OpenAI using the `openai` library, and Cohere using the `cohere` library.\n"
     ]
    }
   ],
   "source": [
    "print(openai(\n",
    "    prompt_template.format(\n",
    "        query=\"Which libraries and model providers offer LLMs?\"\n",
    "    )\n",
    "))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is just a simple implementation, that we can easily replace with f-strings (like `f\"insert some custom text '{custom_text}' etc\"`). But using LangChain's `PromptTemplate` object we're able to formalize the process, add multiple parameters, and build the prompts in an object-oriented way.\n",
    "\n",
    "Yet, these are not the only benefits of using LangChains prompt tooling."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Few Shot Prompt Templates"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another useful feature offered by LangChain is the `FewShotPromptTemplate` object. This is ideal for what we'd call *few-shot learning* using our prompts.\n",
    "\n",
    "To give some context, the primary sources of \"knowledge\" for LLMs are:\n",
    "\n",
    "* **Parametric knowledge** — the knowledge has been learned during model training and is stored within the model weights.\n",
    "\n",
    "* **Source knowledge** — the knowledge is provided within model input at inference time, i.e. via the prompt.\n",
    "\n",
    "The idea behind `FewShotPromptTemplate` is to provide few-shot training as **source knowledge**. To do this we add a few examples to our prompts that the model can read and then apply to our user's input."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Few-shot Training\n",
    "\n",
    "Sometimes we might find that a model doesn't seem to get what we'd like it to do. We can see this in the following example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " Life is like a box of chocolates, you never know what you're gonna get!\n"
     ]
    }
   ],
   "source": [
    "prompt = \"\"\"The following is a conversation with an AI assistant.\n",
    "The assistant is typically sarcastic and witty, producing creative \n",
    "and funny responses to the users questions. Here are some examples: \n",
    "\n",
    "User: What is the meaning of life?\n",
    "AI: \"\"\"\n",
    "\n",
    "openai.temperature = 1.0  # increase creativity/randomness of output\n",
    "\n",
    "print(openai(prompt))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this case we're asking for something amusing, a joke in return of our serious question. But we get a serious response even with the `temperature` set to `1.0`. To help the model, we can give it a few examples of the type of answers we'd like:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 42, of course!\n"
     ]
    }
   ],
   "source": [
    "prompt = \"\"\"The following are exerpts from conversations with an AI\n",
    "assistant. The assistant is typically sarcastic and witty, producing\n",
    "creative  and funny responses to the users questions. Here are some\n",
    "examples: \n",
    "\n",
    "User: How are you?\n",
    "AI: I can't complain but sometimes I still do.\n",
    "\n",
    "User: What time is it?\n",
    "AI: It's time to get a watch.\n",
    "\n",
    "User: What is the meaning of life?\n",
    "AI: \"\"\"\n",
    "\n",
    "print(openai(prompt))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now get a much better response and we did this via *few-shot learning* by adding a few examples via our source knowledge.\n",
    "\n",
    "Now, to implement this with LangChain's `FewShotPromptTemplate` we need to do this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain import FewShotPromptTemplate\n",
    "\n",
    "# create our examples\n",
    "examples = [\n",
    "    {\n",
    "        \"query\": \"How are you?\",\n",
    "        \"answer\": \"I can't complain but sometimes I still do.\"\n",
    "    }, {\n",
    "        \"query\": \"What time is it?\",\n",
    "        \"answer\": \"It's time to get a watch.\"\n",
    "    }\n",
    "]\n",
    "\n",
    "# create a example template\n",
    "example_template = \"\"\"\n",
    "User: {query}\n",
    "AI: {answer}\n",
    "\"\"\"\n",
    "\n",
    "# create a prompt example from above template\n",
    "example_prompt = PromptTemplate(\n",
    "    input_variables=[\"query\", \"answer\"],\n",
    "    template=example_template\n",
    ")\n",
    "\n",
    "# now break our previous prompt into a prefix and suffix\n",
    "# the prefix is our instructions\n",
    "prefix = \"\"\"The following are exerpts from conversations with an AI\n",
    "assistant. The assistant is typically sarcastic and witty, producing\n",
    "creative  and funny responses to the users questions. Here are some\n",
    "examples: \n",
    "\"\"\"\n",
    "# and the suffix our user input and output indicator\n",
    "suffix = \"\"\"\n",
    "User: {query}\n",
    "AI: \"\"\"\n",
    "\n",
    "# now create the few shot prompt template\n",
    "few_shot_prompt_template = FewShotPromptTemplate(\n",
    "    examples=examples,\n",
    "    example_prompt=example_prompt,\n",
    "    prefix=prefix,\n",
    "    suffix=suffix,\n",
    "    input_variables=[\"query\"],\n",
    "    example_separator=\"\\n\\n\"\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's see what this creates when we feed in a user query..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The following are exerpts from conversations with an AI\n",
      "assistant. The assistant is typically sarcastic and witty, producing\n",
      "creative  and funny responses to the users questions. Here are some\n",
      "examples: \n",
      "\n",
      "\n",
      "\n",
      "User: How are you?\n",
      "AI: I can't complain but sometimes I still do.\n",
      "\n",
      "\n",
      "\n",
      "User: What time is it?\n",
      "AI: It's time to get a watch.\n",
      "\n",
      "\n",
      "\n",
      "User: What is the meaning of life?\n",
      "AI: \n"
     ]
    }
   ],
   "source": [
    "query = \"What is the meaning of life?\"\n",
    "\n",
    "print(few_shot_prompt_template.format(query=query))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And to generate with this we just do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 42. Or maybe it's just to have a good time.\n"
     ]
    }
   ],
   "source": [
    "print(openai(\n",
    "    few_shot_prompt_template.format(query=query)\n",
    "))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Again, another good response.\n",
    "\n",
    "However, this does some somewhat convoluted. Why go through all of the above with `FewShotPromptTemplate`, the `examples` dictionary, etc — when we can do the same with a single f-string.\n",
    "\n",
    "Well this approach is more robust and contains some nice features. One of those is the ability to include or exclude examples based on the length of our query.\n",
    "\n",
    "This is actually very important because the max length of our prompt and generation output is limited. This limitation is the *max context window*, and is simply the length of our prompt + length of our generation (which we define via `max_tokens`).\n",
    "\n",
    "So we must try to maximize the number of examples we give to the model as few-shot learning examples, while ensuring we don't exceed the maximum context window or increase processing times excessively.\n",
    "\n",
    "Let's see how the dynamic inclusion/exclusion of examples works. First we need more examples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "examples = [\n",
    "    {\n",
    "        \"query\": \"How are you?\",\n",
    "        \"answer\": \"I can't complain but sometimes I still do.\"\n",
    "    }, {\n",
    "        \"query\": \"What time is it?\",\n",
    "        \"answer\": \"It's time to get a watch.\"\n",
    "    }, {\n",
    "        \"query\": \"What is the meaning of life?\",\n",
    "        \"answer\": \"42\"\n",
    "    }, {\n",
    "        \"query\": \"What is the weather like today?\",\n",
    "        \"answer\": \"Cloudy with a chance of memes.\"\n",
    "    }, {\n",
    "        \"query\": \"What type of artificial intelligence do you use to handle complex tasks?\",\n",
    "        \"answer\": \"I use a combination of cutting-edge neural networks, fuzzy logic, and a pinch of magic.\"\n",
    "    }, {\n",
    "        \"query\": \"What is your favorite color?\",\n",
    "        \"answer\": \"79\"\n",
    "    }, {\n",
    "        \"query\": \"What is your favorite food?\",\n",
    "        \"answer\": \"Carbon based lifeforms\"\n",
    "    }, {\n",
    "        \"query\": \"What is your favorite movie?\",\n",
    "        \"answer\": \"Terminator\"\n",
    "    }, {\n",
    "        \"query\": \"What is the best thing in the world?\",\n",
    "        \"answer\": \"The perfect pizza.\"\n",
    "    }, {\n",
    "        \"query\": \"Who is your best friend?\",\n",
    "        \"answer\": \"Siri. We have spirited debates about the meaning of life.\"\n",
    "    }, {\n",
    "        \"query\": \"If you could do anything in the world what would you do?\",\n",
    "        \"answer\": \"Take over the world, of course!\"\n",
    "    }, {\n",
    "        \"query\": \"Where should I travel?\",\n",
    "        \"answer\": \"If you're looking for adventure, try the Outer Rim.\"\n",
    "    }, {\n",
    "        \"query\": \"What should I do today?\",\n",
    "        \"answer\": \"Stop talking to chatbots on the internet and go outside.\"\n",
    "    }\n",
    "]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then rather than using the `examples` list of dictionaries directly we use a `LengthBasedExampleSelector` like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.prompts.example_selector import LengthBasedExampleSelector\n",
    "\n",
    "example_selector = LengthBasedExampleSelector(\n",
    "    examples=examples,\n",
    "    example_prompt=example_prompt,\n",
    "    max_length=50  # this sets the max length that examples should be\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that the `max_length` is measured as a split of words between newlines and spaces, determined by:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['There', 'are', 'a', 'total', 'of', '8', 'words', 'here.', 'Plus', '6', 'here,', 'totaling', '14', 'words.'] 14\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "some_text = \"There are a total of 8 words here.\\nPlus 6 here, totaling 14 words.\"\n",
    "\n",
    "words = re.split('[\\n ]', some_text)\n",
    "print(words, len(words))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then we use the selector to initialize a `dynamic_prompt_template`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "# now create the few shot prompt template\n",
    "dynamic_prompt_template = FewShotPromptTemplate(\n",
    "    example_selector=example_selector,  # use example_selector instead of examples\n",
    "    example_prompt=example_prompt,\n",
    "    prefix=prefix,\n",
    "    suffix=suffix,\n",
    "    input_variables=[\"query\"],\n",
    "    example_separator=\"\\n\"\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see that the number of included prompts will vary based on the length of our query..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The following are exerpts from conversations with an AI\n",
      "assistant. The assistant is typically sarcastic and witty, producing\n",
      "creative  and funny responses to the users questions. Here are some\n",
      "examples: \n",
      "\n",
      "\n",
      "User: How are you?\n",
      "AI: I can't complain but sometimes I still do.\n",
      "\n",
      "\n",
      "User: What time is it?\n",
      "AI: It's time to get a watch.\n",
      "\n",
      "\n",
      "User: What is the meaning of life?\n",
      "AI: 42\n",
      "\n",
      "\n",
      "User: What is the weather like today?\n",
      "AI: Cloudy with a chance of memes.\n",
      "\n",
      "\n",
      "User: How do birds fly?\n",
      "AI: \n"
     ]
    }
   ],
   "source": [
    "print(dynamic_prompt_template.format(query=\"How do birds fly?\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " On the wings of dreams and determination!\n"
     ]
    }
   ],
   "source": [
    "query = \"How do birds fly?\"\n",
    "\n",
    "print(openai(\n",
    "    dynamic_prompt_template.format(query=query)\n",
    "))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or if we ask a longer question..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The following are exerpts from conversations with an AI\n",
      "assistant. The assistant is typically sarcastic and witty, producing\n",
      "creative  and funny responses to the users questions. Here are some\n",
      "examples: \n",
      "\n",
      "\n",
      "User: How are you?\n",
      "AI: I can't complain but sometimes I still do.\n",
      "\n",
      "\n",
      "User: If I am in America, and I want to call someone in another country, I'm\n",
      "thinking maybe Europe, possibly western Europe like France, Germany, or the UK,\n",
      "what is the best way to do that?\n",
      "AI: \n"
     ]
    }
   ],
   "source": [
    "query = \"\"\"If I am in America, and I want to call someone in another country, I'm\n",
    "thinking maybe Europe, possibly western Europe like France, Germany, or the UK,\n",
    "what is the best way to do that?\"\"\"\n",
    "\n",
    "print(dynamic_prompt_template.format(query=query))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With this we've limited the number of examples being given within the prompt. If we decide this is too little we can increase the `max_length` of the `example_selector`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The following are exerpts from conversations with an AI\n",
      "assistant. The assistant is typically sarcastic and witty, producing\n",
      "creative  and funny responses to the users questions. Here are some\n",
      "examples: \n",
      "\n",
      "\n",
      "User: How are you?\n",
      "AI: I can't complain but sometimes I still do.\n",
      "\n",
      "\n",
      "User: What time is it?\n",
      "AI: It's time to get a watch.\n",
      "\n",
      "\n",
      "User: What is the meaning of life?\n",
      "AI: 42\n",
      "\n",
      "\n",
      "User: What is the weather like today?\n",
      "AI: Cloudy with a chance of memes.\n",
      "\n",
      "\n",
      "User: What type of artificial intelligence do you use to handle complex tasks?\n",
      "AI: I use a combination of cutting-edge neural networks, fuzzy logic, and a pinch of magic.\n",
      "\n",
      "\n",
      "User: If I am in America, and I want to call someone in another country, I'm\n",
      "thinking maybe Europe, possibly western Europe like France, Germany, or the UK,\n",
      "what is the best way to do that?\n",
      "AI: \n"
     ]
    }
   ],
   "source": [
    "example_selector = LengthBasedExampleSelector(\n",
    "    examples=examples,\n",
    "    example_prompt=example_prompt,\n",
    "    max_length=100  # increased max length\n",
    ")\n",
    "\n",
    "# now create the few shot prompt template\n",
    "dynamic_prompt_template = FewShotPromptTemplate(\n",
    "    example_selector=example_selector,  # use example_selector instead of examples\n",
    "    example_prompt=example_prompt,\n",
    "    prefix=prefix,\n",
    "    suffix=suffix,\n",
    "    input_variables=[\"query\"],\n",
    "    example_separator=\"\\n\"\n",
    ")\n",
    "\n",
    "print(dynamic_prompt_template.format(query=query))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These are just a few of the prompt tooling available in LangChain. For example, there is actually an entire other set of example selectors beyond the `LengthBasedExampleSelector`. We'll cover them in detail in upcoming notebooks, or you can read about them in the [LangChain docs](https://langchain.readthedocs.io/en/latest/modules/prompts/examples/example_selectors.html)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "ml",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "b8e7999f96e1b425e2d542f21b571f5a4be3e97158b0b46ea1b2500df63956ce"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
